;# PernsonData und PersonData2 are
;# the main Pointers. The other adresses
;# are calculated on their base as
;# following:
;#
;# PersonData 		= PersonExists (0/1)
;# PersonData + 0x25	= MapID
;# PersonData +	0x27	= PosX
;# PersonData +	0x29	= PosY
;# PersonData +	0x3F	= CharName
;# PersonData2 		= Guild ID
;# PersonData2 + 0x4	= Full Char name (incl. Title and Div.)
;# PersonData2 + 0x76	= Guild Name	
;# 
;# For Person-Selection:
;# 	Starting with x=0 for first Person
;# 
;# PersonData:
;# 	$Offset_2 + x * 0x4
;# 
;# PersonData2:
;# 	$Offset_2 + x * 0x4


#Include Lib\ReadMemory.ahk
#Include Lib\WriteMemory.ahk
#Include Lib\ImageFunctions.ahk

;


getABStatus() {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x12764
	x:=ReadMemory(p1,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return x
}



getABNumber(){
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x12768
	x:=ReadMemory(p1,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return x	
}





setAutoMapId(mapNumber) {
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x894
	WriteMemoryShortInt(mapNumber,p3,"Atlantica")
	
}

setAutoMapX(posx) {
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x896
	WriteMemoryShortInt(posx,p3,"Atlantica")
	
}


setAutoMapY(posy) {
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x898
	
	WriteMemoryShortInt(posy,p3,"Atlantica")
	
}

toggleAutoMove(b){
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x88E
	
	WriteMemoryByte(b,p3,"Atlantica")
}


AutoMove(posx,posy,mapid) {
	toggleAutoMove(0)
	sleep, 5
	setAutoMapID(mapid)
	setAutoMapX(posx)
	setAutoMapY(posy)
	toggleAutoMove(1)
}


getInCombat(){
	x:=ReadMemory(0x0F2D7fC,"Atlantica")
	;msgbox, combatmem:%x%
	return x
}

getMapID(){
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAA
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	Return x
}


GetX() {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAC
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	Return x
}



GetY() {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xc
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAE
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	Return x
}


SetRunspeed(r) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x284
	WriteMemory(r,p3,"Atlantica")
	SetFormat,IntegerFast,d
}

GetRunspeed(){
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x284
	x:=ReadMemory(p3,"Atlantica")
	SetFormat,IntegerFast,d
	return x
}

incRunSpeed() {
	x:=GetRunspeed()
	x+=10
	if (x>70) {
		x:=70
	}
	SetRunSpeed(x)
	tooltip, RunSpeed: %x%
	sleep, 500
	ToolTip
	}
	
decRunSpeed() {
	x:=GetRunspeed()
	x-=10
	if (x<0){ 
		x:=0
	}
	SetRunSpeed(x)
	tooltip, RunSpeed: %x%
	sleep, 500
	ToolTip
	}


SetSpeed(s){
	WriteMemory(s, 0xEE2658,"Atlantica")
}
;Atlantica.exe+F957E0

ReadCursor() {
	Process, exist, Atlantica.exe
	static cpid:=ErrorLevel
	
	static hand
	static sword
	static pickup
	if (!hand || cpid!=ErrorLevel) {
		cpid:=ErrorLevelffffff
		SetFormat,IntegerFast,hex
		cursorbase:= 0xEB2A58
		cursor_p := ReadMemory(cursorbase,"Atlantica")
		cursor_p += 0xB28
		cursor:=ReadMemory(cursor_p,"Atlantica")
		hand_a := cursor+0x4
		sword_a := cursor+0x10
		pickup_a := cursor+0x14
		hand := ReadMemory(hand_a,"Atlantica")
		sword := ReadMemory(sword_a,"Atlantica")
		pickup := ReadMemory(pickup_a,"Atlantica")
		SetFormat,IntegerFast,d
		hand+=0
		sword+=0
		pickup+=0
	}

 	
	NumPut(VarSetCapacity(cursorInfo, A_PtrSize + 16), cursorInfo, "Uint"), DllCall("GetCursorInfo", "Uint", &cursorInfo, "Uint" )
	hi := NumGet(cursorInfo, 8)
	xi:=Num2Bin(hi,32)
	xi:=Bin2Num(xi)
	;return xi
	;msgbox, %sword_a%
	if (xi=hand) {

		return, 0
		}
	if (xi=sword) {

		return, 1
	}
	if (xi=pickup) {

		return, 2
	}  
	return, -1
		
}
setZoom(z) {   ; fora de batalha
	SetFormat,IntegerFast,hex
	z:=FloatToHex(z)
	zoombase:= 0xF2D7F4
	zoom_p := ReadMemory(zoombase,"Atlantica")
	zoom_p += 0x38
	zoom_p2:=ReadMemory(zoom_p,"Atlantica")
	zoom_1:= zoom_p2+0x70
	zoom_2:= zoom_p2+0x100
	zoom_3:= zoom_p2+0x104
	zoom_4:= zoom_p2+0x128
	zoom_b:= zoom_p2+0xFC
	WriteMemory(z,zoom_1,"Atlantica")
	
	WriteMemory(z,zoom_2,"Atlantica")
	WriteMemory(z,zoom_3,"Atlantica")
	WriteMemory(z,zoom_4,"Atlantica")
	WriteMemory(z,zoom_b,"Atlantica")
	SetFormat,IntegerFast,d
}


SetBattleZoom(z) {
	SetFormat,IntegerFast,hex
	z:=FloatToHex(z)
	zoombase:= 0xF2D7F4
	zoom_p := ReadMemory(zoombase,"Atlantica")
	zoom_p += 0x2AC
	zoom_p2:=ReadMemory(zoom_p,"Atlantica")
	zoom_1:= zoom_p2+0x70
	zoom_2:= zoom_p2+0x100
	zoom_3:= zoom_p2+0x104
	zoom_4:= zoom_p2+0x128
	zoom_b:= zoom_p2+0xFC
	WriteMemory(z,zoom_1,"Atlantica")
	WriteMemory(z,zoom_2,"Atlantica")
	WriteMemory(z,zoom_3,"Atlantica")
	WriteMemory(z,zoom_4,"Atlantica")
	WriteMemory(z,zoom_b,"Atlantica")
	SetFormat,IntegerFast,d
}



SetCamera(d) {  ; angulo horizontal
	SetFormat,IntegerFast,hex
	d:=FloatToHex(d)
	camerabase:= 0xF2D7F4
	camera_p := ReadMemory(camerabase,"Atlantica")
	camera_p += 0x38
	camera_p2:=ReadMemory(camera_p,"Atlantica")
	camera:= camera_p2+0xDC
	;msgbox %camera%
	WriteMemory(d,camera,"Atlantica")
	SetFormat,IntegerFast,d
}

FloatToHex(f) {
   form := A_FormatInteger
   SetFormat Integer, HEX
   v := DllCall("MulDiv", Float,f, Int,1, Int,1, UInt)
   SetFormat Integer, %form%
   Return v
}

decodeInteger(ptr) {
return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}



Num2Bin(n,bits=0) {     ; Return LS "bits" of binary representation of "n"
   IfLess bits,1, Loop  ; n < 0: leading 1's are omitted. -1 -> 1, 0 -> 0
      {
         b := n&1 b
         n := n>>1
         If (n = n>>1)
            Break
      }
   Else Loop %bits%
      {
         b := n&1 b
         n := n>>1
      }
   Return b
}


Bin2Num(bits,neg="") {  ; Return number converted from the binary "bits" string
   n = 0                ; If "neg" is not 0 or empty, 11..1 assumed on the left
   Loop Parse, bits
      n += n + A_LoopField
   Return n - !(neg<1)*(1<<StrLen(bits))
}

GetTurn() {
	if (!inBattle()){
		return, -1
	}
    SetFormat,IntegerFast,hex
    ;base:=0x13105E8
	base:=0xEB2A58

    p1:=ReadMemory(base,"Atlantica")
    p1+=0x8EC
    p2:=ReadMemory(p1,"Atlantica")
    p2+=0x8
    p3:=ReadMemory(p2,"Atlantica")
    p3+=0x7A50
    ;7A50
	turn:=ReadMemory(p3,"Atlantica")
	SetFormat,IntegerFast,d
	turn+=0
	return, turn
}

getHP(char) {
    SetFormat,IntegerFast,hex
	hp:=0
    base:=0xEB2A58
    ap_p1:=ReadMemory(base,"Atlantica")
    ap_p1+=0x800
    ap_p2:=ReadMemory(ap_p1,"Atlantica")
    ap_p2+=0xc
    ap_p3:=ReadMemory(ap_p2,"Atlantica")
    ap_p3+=0x30
    ap_p4:=ReadMemory(ap_p3,"Atlantica")
    ap_p4+=0x1e60
	ap_p4+=(char-1)*0x788
	hp:=ReadMemory(ap_p4,"Atlantica")
	SetFormat,IntegerFast,d
	hp+=0
	;sleep, 100
	return, hp
}

getMP(char) {
    SetFormat,IntegerFast,hex
    base:=0xEB2A58
    ap_p1:=ReadMemory(base,"Atlantica")
    ap_p1+=0x800
    ap_p2:=ReadMemory(ap_p1,"Atlantica")
    ap_p2+=0xc
    ap_p3:=ReadMemory(ap_p2,"Atlantica")
    ap_p3+=0x30
    ap_p4:=ReadMemory(ap_p3,"Atlantica")
    ap_p4+=0x1E64
	ap_p4+=(char-1)*0x788
	mp:=ReadMemory(ap_p4,"Atlantica")
	SetFormat,IntegerFast,d
	mp+=0
	return, mp
}

getActiveChar() {
	
	SetFormat,IntegerFast,hex
	
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x11454
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x4c
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x4a8
	char:=ReadMemory(p3,"Atlantica")
	SetFormat,IntegerFast,d
	char+=1
	return char
}

getCombo(char) {
    SetFormat,IntegerFast,hex
    base:=0x13105E8
    ap_p1:=ReadMemory(base,"Atlantica")
    ap_p1+=0x800
    ap_p2:=ReadMemory(ap_p1,"Atlantica")
    ap_p2+=0xC
    ap_p3:=ReadMemory(ap_p2,"Atlantica")
    ap_p3+=0x30
    ap_p4:=ReadMemory(ap_p3,"Atlantica")
    ap_p4+=0xE4BF
	ap_p4+=(char-1)*0x30
	combo:=ReadMemoryByte(ap_p4,"Atlantica")
	SetFormat,IntegerFast,d
	combo+=0
	return, combo
}


getCharName() {
	winget, prid, PID, Atlantica
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0xC
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xC4
	x:=ReadMemory_Str(p4)
	SetFormat,IntegerFast,d
	Return x
	
}

getNearX(pos) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x10 + (4*pos)
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAC
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return, x
	}
	


getNearY(pos) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x10 + (4*pos)
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xAE
	x:=ReadMemoryShortInt(p4,"Atlantica")
	SetFormat,IntegerFast,d
	x+=0
	return, x
	}



getNome(pos) {
	SetFormat,IntegerFast,hex
	base:=0xEB2A58
	p1:=ReadMemory(base,"Atlantica")
	p1+=0x800
	p2:=ReadMemory(p1,"Atlantica")
	p2+=0x10 + (4*pos)
	p3:=ReadMemory(p2,"Atlantica")
	p3+=0x30
	p4:=ReadMemory(p3,"Atlantica")
	p4+=0xC4
	name:=ReadMemory_str(p4)
	SetFormat,IntegerFast,d
	return, name
	
	
}

getMPDeficit(){
		
		static maxmp:=Object()
		static mp:=Object()
		mpdeficittotal=0
		
		loop, 9 {
			mp[A_Index]:=getMP(A_Index)
		    if (mp[A_Index]>maxmp[A_Index]) {
				maxmp[A_Index]:=mp[A_Index]
			}	
			mpdeficittotal+=(maxmp[A_Index]-mp[A_Index])
		}
	return mpdeficittotal
	}
	
getHPDeficit() {
		
		static maxhp:=Object()
		static hp:=Object()
		hpdeficittotal=0
		
		loop, 9 {
			hp[A_Index]:=getHP(A_Index)
		    if (hp[A_Index]>maxhp[A_Index]) {
				maxhp[A_Index]:=hp[A_Index]
			}	
			hpdeficittotal+=(maxhp[A_Index]-hp[A_Index])
		}
	return hpdeficittotal
	
	
}
	
getDeadMercs() {
	static hp:=Object()
	retorno:=0
	loop, 9 {
		hp[A_Index]:=getHP(A_Index)
		if (hp[A_Index]=0) {
			retorno++
		}	
	}
	return retorno
	}

closestMob() {
	i:=1
	posd:=999
	posi:=-1
	while (i<30) {
		nome:=getNome(i)
		Loop, read, %A_WorkingDir%\moblist.txt
		{
			Loop, parse, A_LoopReadLine, %A_Tab%
			{
				If (InStr(nome, A_LoopField)){
					x:=getNearX(i)
					y:=getNearY(i)
					myX:=getX()
					myY:=getY()
					dist:=getDistanceD(x,y,myX,myY)
					if (dist<posd) {
						posd:=dist
						posi:=i
					}
					;msgbox, %i% %nome% %x% %y% %dist%
				}
		
			}
		}


		
		i++
	}
	if (posi=-1) {
		msgbox, sem mobs validos
		return
	}
	nome:=getNome(posi)
	x:=getNearX(posi)
	y:=getNearY(posi)
	tooltip , closest %nome% %x% %y% %dist%, 0, 0, 1
	AutoMove(x,y,getMapID())

	return, posi
	
}

faceMob(posi) {
	myX:=getX()
	myY:=getY()
	x:=getNearX(posi)
	y:=getNearY(posi)
	
	dist:=getDistanceD(x,y,myX,myY)
	nome:=getNome(posi)
	tooltip , facing %nome% %x% %y% %dist%, 0, 0, 1
	xdif:=x-GetX()
	ydif:=y-GetY()
	if (xdif=0 && ydif>0) {
		SetCamera(1.57)
	}
	else if (xdif=0 && ydif<0) {
		SetCamera(4.71)
	}
	else if (xdif>0 && ydif>0) {
		SetCamera(0.78)
	}
	else if (xdif<0 && ydif<0) {
		SetCamera(5.49)
	}
	else if (xdif=0 && ydif>0) {
		SetCamera(0.0)
	}
	else {
		SetCamera(3.14)
	}
	send, {w down}
	sleep, 25
	send {w up}
	

}

 worldTour() {
		i:=30
		while (i<66) {
			automove(0,0,i)
			tooltip, cidade %i% , 0, 0, 1
			SetRunspeed(35)
			if (getMapID()=i) {
				i++
				automove(0,0,i)
				sleep, 20000
				}
			sleep, 5000
		}
	}
	
getDistance() {
	global autox
	global autoy
	d:=sqrt((getX()-autox)**2+(getY()-autoy)**2)
	return d
	}
	
	getDistanceD(x1, y1, x2, y2) {
	d:=sqrt((x1-x2)**2+(y1-y2)**2)
	return d 
	}
	
	
returnToSpot() {
	global maxdistance
	global autox
	global autoy
	global automapid
	distance:=getDistance()
	if (maxdistance!=-1 && distance > maxdistance) {
		automove(autox,autoy,automapid)
		while (15<distance) {
			oldX:=GetX()
			oldY:=getY()
			sleep, 2500
			x:=getX()
			y:=getY()
			d:=sqrt((x-oldX)**2+(y-oldY)**2)
			if (d<4) {
				paranoid()
				Send , {s down}
				sleep, 3000
				send , {s up}
			}
			automove(autox,autoy,automapid)
			distance:=getDistance()
			tooltip, distance:%distance%,0, 0, 1
		}
		send, w
		sleep, 300
		ImageSearch, sx, sy, 0, 0, 1000, 1000, *20 Images\Misc\sim.png
		MouseClick, left, sx, sy
	}
}

FPV(){
	SetBattleZoom(0.0)
	;SetCamera(0.0)
}

paranoid(){
	globalVars()
	global paranoid
	global automapid ; se -1 auto-run back off.
	global autox
	global autoy
	
	global automapid2
	global autox2
	global autoy2
	
	global automapid3
	global autox3
	global autoy3
	
	static ltele:=A_Now
	static cresc:=0
	
	mob:=0
	i:=1
	
	if (paranoid>0 && (getMapID()>72 || (getMapID()=0))){          
		loop {
			sentinela:=0
			mob:=0
			while (i<45) {
				nome:=getNome(i)
				;msgbox, %nome%
				;nome:="paunocussj"
				Loop, read, %A_WorkingDir%\moblist.txt
				{
					Loop, parse, A_LoopReadLine, %A_Tab%
					{
						StringLen, length, nome
						If (InStr(nome, A_LoopField)){
							mob:=1
							break
						}
						else if (length=0 || InStr(nome, "Ravock") || InStr(nome, "Zuy") || InStr(nome, "Apsalar") || InStr(nome, "Blacklycan") || InStr(nome, "Xima") || InStr(nome,"StarRock")) {
							mob:=1
							break
						}
					}
				}
				if (mob=0) {
					while (getMapId()!=1) {
						tpToHanyang()
					}
					now:=A_Now
					EnvSub, ltele, now, minutes
					rmin:=cresc+60
					rmax:=cresc+120
					Random, r, rmin, rmax
					if (r<360) {
						cresc+=60
					}
					else {
						cresc:=0
					}
					ltele:=A_Now
					elapsed:=0
					while (elapsed<r) {
						automove(164,191,1)
						;now:=A_Now
						EnvSub, elapsed, now, seconds
						
						;x:=getNearX(i)
						;y:=getNearY(i)
						sentinela:=1
					    tooltip, ESPERANDO tempo:%elapsed%/%r% douchebag:%nome% , 0, 0, 1 
						sleep, 1000
					}
				if (automapid2>-1 && automapid3<0) {
					tmpmap:=automapid
					tmpx:=autox
					tmpy:=autoy
					
					global automapid:=automapid2
					global autox:=autox2
					global autoy:=autoy2
					
					global automapid2:=tmpmap
					global autox2:=tmpx
					global autoy2:=tmpy
					amIDead(automapid,autox,autoy)
					}
				else if (automapid2>-1 && automapid3>-1) {
					tmpmap:=automapid
					tmpx:=autox
					tmpy:=autoy
					
					global automapid:=automapid2
					global autox:=autox2
					global autoy:=autoy2
					
					global automapid2:=automapid3
					global autox2:=autox3
					global autoy2:=autoy3
					
					global automapid3:=tmpmap
					global autox3:=tmpx
					global autoy3:=tmpy
					amIDead(automapid,autox,autoy)
				}
				
				paranoid()
				}
			i++
			mob:=0
			}
		if (sentinela=0) {
			break
		}
	}
}

}


setPID() {
	global gpid
	WinGet, gpid, PID, Atlantica Online
}